package com.xuzimian.globaldemo.spring.springrpc.webconfig;

import java.util.Properties;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.caucho.BurlapServiceExporter;
import org.springframework.remoting.caucho.HessianServiceExporter;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;

import com.xuzimian.globaldemo.spring.springrpc.RemoteServerPublisService;
import com.xuzimian.globaldemo.spring.springrpc.RemoteServerPublisServiceImpl;
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * 该类配置了需要导出为http服务的各种协议版本hessian,burlap,httpinvoker.以及为springmvc注册必要的http处理器映射器
 */
@Configuration
public class SpringConfig {


	@Bean("serverBean")
	public RemoteServerPublisService remoteServerPublisServiceBean() {
		return new RemoteServerPublisServiceImpl("hessianService");
	}

	/**
	 * 导出一个服务为Hessian服务
	 * @param remoteServerPublisService
	 * @return
	 */
	@Bean
	public HessianServiceExporter hessianExporterService(@Qualifier("serverBean")RemoteServerPublisService remoteServerPublisService) {
		HessianServiceExporter exporter = new HessianServiceExporter();
		exporter.setService(remoteServerPublisService);
		exporter.setServiceInterface(RemoteServerPublisService.class);
		return exporter;
	}

	/**
	 *   将请求(/hessianremote.hessianservice)映射到hessianExporterService服务上
	 * @return
	 */
	@Bean
	public HandlerMapping hessianMapping() {
		SimpleUrlHandlerMapping mapping=new SimpleUrlHandlerMapping();
		Properties maProperties=new Properties();
		maProperties.setProperty("/xx/hessianremote.hessianservice", "hessianExporterService");
		mapping.setMappings(maProperties);
		return mapping;
	}


	/**
	 * 导出一个服务为Burlap服务。
	 * Spring 不推荐使用 Burlap，BurlapServiceExporter 在4.0后被废弃，不再提供支持。
	 * @param remoteServerPublisService
	 * @return
	 */
	@Bean
	public BurlapServiceExporter burlapExporterService(@Qualifier("serverBean")RemoteServerPublisService remoteServerPublisService) {
		BurlapServiceExporter exporter = new BurlapServiceExporter();
		exporter.setService(remoteServerPublisService);
		exporter.setServiceInterface(RemoteServerPublisService.class);
		return exporter;
	}

	/**
	 *   将请求(/burlapremote.burlapservice)映射到burlapExporterService服务上
	 * @return
	 */
	@Bean
	public HandlerMapping burlapMapping() {
		SimpleUrlHandlerMapping mapping=new SimpleUrlHandlerMapping();
		Properties maProperties=new Properties();
		maProperties.setProperty("/xx/burlapremote.burlapservice", "burlapExporterService");
		mapping.setMappings(maProperties);
		return mapping;
	}



	/**
	 * 导出一个服务为HttpInvoker服务
	 * @param remoteServerPublisService
	 * @return
	 */
	@Bean
	public HttpInvokerServiceExporter httpInvokerExporterService(@Qualifier("serverBean")RemoteServerPublisService remoteServerPublisService) {
		HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
		exporter.setService(remoteServerPublisService);
		exporter.setServiceInterface(RemoteServerPublisService.class);
		return exporter;
	}

	/**
	 *   将请求(/burlapremote.burlapservice)映射到burlapExporterService服务上
	 * @return
	 */
	@Bean
	public HandlerMapping httpInvokerMapping() {
		SimpleUrlHandlerMapping mapping=new SimpleUrlHandlerMapping();
		Properties maProperties=new Properties();
		maProperties.setProperty("/xx/httpInvokerremote.httpInvokerservice", "httpInvokerExporterService");
		mapping.setMappings(maProperties);
		return mapping;
	}



	/**
	 * BeanNameUrlHandlerMapping 会自动探测 '/' 开头的bean当做是一个handler，
	 * 但默认是只探测当前context里的bean，不会探测ancestor contexts(父容器)，
	 * 如果要探测父容器，那么设置detectHandlersInAncestorContexts为true
	 * @return
	 */
	@Bean
	public HandlerMapping beanNameUrlHandlerMapping() {
		return new  BeanNameUrlHandlerMapping();
	}

	/**
	 * 注册通过扫描注解controller的处理器映射器
	 * 默认情况下springmvc会自动注册BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping这两个处理器，
	 * 但是当上面手动配置了SimpleUrlHandlerMapping处理器映射器以后，就默认只有这一个处理器，因此，当你还需要
	 * springmvc自动解析对controller类上方法的http映射，就需要手动配置该映射器处理器。
	 * SpringMVC默认注册处理器映射器，可参考源码：DispatcherServlet 的 initHandlerMappings方法
	 * @return
	 */
	@Bean
	public HandlerMapping defaultAnnotationHandlerMapping() {
		//spring 5 以上已经没有这个类了 new DefaultAnnotationHandlerMapping();
		return new RequestMappingHandlerMapping();
	}

}
